#!/usr/bin/env python
import sys
from qt import *
import threading
import qt
import subprocess
import os
import gettext
import tools_lib
import wizard_ui
import wizard_qt_lib


class MainQtWindow(wizard_ui.WizardUi):
    def __init__(self, frontend, backend, *args):
        self.initWidgetNamePagesNames()
        self.pages={}
        apply(wizard_ui.WizardUi.__init__, (self,) + args)
        self.setCaption(_("One click installer"))
        self.simpleChoiceButtons = {}
        
        self.simpleChoiceRadioGroup.setColumnLayout(0,Qt.Vertical)
        self.simpleChoiceRadioGroup.layout().setSpacing(6)
        self.simpleChoiceRadioGroup.layout().setMargin(11)
        
        self.frontend = frontend
        self.backend = backend
        self.backButton().setText(_("Back"))
        self.nextButton().setText(_("Next"))
        self.finishButton().setText(_("Finish"))
        self.cancelButton().setText(_("Cancel"))
        self.helpButton().setText(_("Help"))
        self.connect(
            self.frontend,
            PYSIGNAL("setNextPage"),
            self.slotSetNextPage
            )
        self.connect(
            self.frontend,
            PYSIGNAL("progressInfo"),
            self.slotProgressInfo
            )
        self.connect(
            self.frontend,
            PYSIGNAL("showFatalError"),
            self.slotShowFatalError
            )
        self.connect(
            self.frontend,
            PYSIGNAL("showPopupDialog"),
            self.slotShowPopupDialog
            )
        self.connect(
            self,
            PYSIGNAL("signalGetPageOutput"),
            self.frontend.slotGetPageOutput
            )
        self.connect(
            self.progressDetailsButton,
            qt.SIGNAL("clicked()"),
            self.toggleProgressDetails
            )
        self.connect(
            self.forceTerminationButton,
            qt.SIGNAL("clicked()"),
            self.forceBackendTermination
            )
        page0 = qt.QWizard.page(self, 0)
        self.currentPageOptions = {}
        #self.setNextEnabled(page0, False)
        #self.setFinishEnabled(page0, False)
        
        self.backend.startWizard()
    def currentPageName(self):
        for (pageName, page) in self.pages.iteritems():
            if page == self.currentPage():
                return pageName
        raise Exception, "Cannot find current page name, pageIndex=%s" % self.indexOf(self.currentPage())
    def enterOperationProgressPage(self):
        self.setNextEnabled(self.currentPage(), False)
        self.progressLabel.setText("")
        if self.currentPageOptions.has_key("progressLabel"):
            self.progressLabel.setText(self.currentPageOptions["progressLabel"])
        self.progressLogText = ""
        self.errorsFrame.hide()
        self.progressLog.hide()
    def enterSimpleChoicePage(self):
        self.setNextEnabled(self.currentPage(), True)
        self.simpleChoiceText.setText(self.currentPageOptions.get("text", ""))
        self.simpleChoiceButtons = {}
        for choiceKey, choiceParams in self.currentPageOptions["choices"].iteritems():
            print "Adding choice: %s params=%s" % (choiceKey, repr(choiceParams))
            button = qt.QRadioButton(self.simpleChoiceRadioGroup)
            self.simpleChoiceRadioGroup.layout().addWidget(button)
            button.setText(choiceParams["text"])
            button.setEnabled(choiceParams.get("enabled", True))
            button.setChecked(choiceParams.get("checked", False))
            button.show()
            self.simpleChoiceButtons[choiceKey] = button
    def enterSimpleMultichoicePage(self):
        self.setNextEnabled(self.currentPage(), True)
        self.simpleMultichoiceText.setText(self.currentPageOptions.get("text", ""))
        self.simpleMultichoiceButtons = {}
        for choiceParams in self.currentPageOptions["choices"]:
            choiceKey = choiceParams["id"]
            print "Adding choice: %s params=%s" % (choiceKey, repr(choiceParams))
            button = qt.QCheckBox(self.simpleMultiChoiceButtonGroup)
            self.simpleMultiChoiceButtonGroup.layout().addWidget(button)
            button.setText(choiceParams["text"])
            label = qt.QLabel(self.simpleMultiChoiceButtonGroup)
            self.simpleMultiChoiceButtonGroup.layout().addWidget(label)
            label.setText(choiceParams["description"])
            button.setEnabled(choiceParams.get("enabled", True))
            button.setChecked(choiceParams.get("checked", False))
            button.show()
            label.show()
            self.simpleMultichoiceButtons[choiceKey] = button
    def enterSimpleMessagePage(self):
        self.simpleMessageText.setText(self.currentPageOptions.get("text", ""))
    def enterTerminationPage(self):
        self.setNextEnabled(self.currentPage(), False)
        self.setFinishEnabled(self.currentPage(), False)
        self.terminationCounter = 0
        self.checkBackendTermination()
        self.terminationTimer = qt.QTimer(self)
        self.connect(
            self.terminationTimer, 
            qt.SIGNAL("timeout()"), 
            self.checkBackendTermination
            )
        self.terminationTimer.start(200) #200 ms timer
        self.frontend.requestBackendTermination()
    def forceBackendTermination(self):
        self.frontend.requestBackendTermination(force = True)
    def checkBackendTermination(self):
        print "Checking if backend terminated"
        if self.frontend.isBackendTerminated() == True:
            print "Backend terminated, closing"
            qt.QWizard.reject(self)
        else:
            print "Backend not terminated, waiting"
            self.terminationCounter = (self.terminationCounter + 1) % 4
            dots = "." * self.terminationCounter
            self.terminationLabel.setText(_("Waiting for background tasks termination") + dots)
    def toggleProgressDetails(self):
        print  "Progress details button clicked"
        if self.progressLog.isHidden():
            self.progressLog.show()
        else:
            self.progressLog.hide()
    def enableButtonNext(self, id):
        self.setNextEnabled(self.currentPage(), True)
    def getSimpleChoicePageOutput(self):
        for choiceLabel, choiceButton in self.simpleChoiceButtons.iteritems():
            if choiceButton.isChecked():
                chosenButton = choiceLabel
            choiceButton.close()
        return {"choice": chosenButton}
    def getSimpleMultichoicePageOutput(self):
        choices = []
        for choiceLabel, choiceButton in self.simpleMultichoiceButtons.iteritems():
            if choiceButton.isChecked():
                choices.append(choiceLabel)
            choiceButton.close()
        return {"choices": choices}
    def reject(self):
        options = {"pageName": "terminating"}
        self.slotSetNextPage(options)
    def showPage(self, page):
        qt.QWizard.showPage(self, page)
        pageName = self.currentPageName()
        print "Entering page: %s" % pageName
        if pageName == "actionProgress":
            self.enterOperationProgressPage()
        elif pageName == "simpleChoice":
            self.enterSimpleChoicePage()
        elif pageName == "simpleMultichoice":
            self.enterSimpleMultichoicePage()
        elif pageName == "simpleMessage":
            self.enterSimpleMessagePage()
        elif pageName == "terminating":
            self.enterTerminationPage()
    def getPageOutput(self):
        pageName = self.currentPageName()
        if pageName == "simpleChoice":
            return self.getSimpleChoicePageOutput()
        elif pageName == "simpleMultichoice":
            return self.getSimpleMultichoicePageOutput()
        else:
            return {}
    def next(self):
        pageOutput = self.getPageOutput()
        print "Emitting signalGetPageOutput, pageOutput=%s" % repr(pageOutput)
        self.emit(PYSIGNAL("signalGetPageOutput"), (pageOutput,))
        #self.setNextEnabled(self.currentPage(), False)
        #self.setFinishEnabled(self.currentPage(), False)
    def initWidgetNamePagesNames(self):
        self.addPageIndex = 0
        self.widgetNamePagesNames = [ 
            "actionProgress", "terminating", "simpleChoice", "simpleMessage", "simpleMultichoice", "finish"
            ]
    def addPage(self, pageWidget, pageName):
        if self.addPageIndex < len(self.widgetNamePagesNames):
            pageName = self.widgetNamePagesNames[self.addPageIndex]
        else:
            pageName = "page%s" % self.addPageIndex
        print "addPage: addPageIndex=%s widgetName=%s pageName=%s" % (self.addPageIndex, pageWidget.name(), pageName)
        self.pages[pageName] = pageWidget
        self.addPageIndex += 1
        qt.QWizard.addPage(self, pageWidget, pageName)
    def slotSetNextPage(self, pageOptions):
        print "slotSetNextPage: pageOptions=%s" % repr(pageOptions)
        nextPageName = pageOptions["pageName"]
        selectedPage = None
        for (pageName, page) in self.pages.iteritems():
            if pageName == nextPageName:
                #self.setAppropriate(page, True)
                selectedPage = page
            else:
                #self.setAppropriate(page, False)
                pass
        self.currentPageOptions = pageOptions
        #qt.QWizard.next(self)
        self.showPage(selectedPage)
        if pageOptions.has_key("nextEnabled"):
            self.setNextEnabled(self.currentPage(), pageOptions["nextEnabled"])
        if pageOptions.has_key("finishEnabled"):
            self.setFinishEnabled(self.currentPage(), pageOptions["finishEnabled"])
        if self.currentPageOptions.has_key("pageTitle"):
            self.setTitle(self.currentPage(), self.currentPageOptions["pageTitle"])
        self.setBackEnabled(self.currentPage(), False) #not supported yet
    def slotShowFatalError(self, options):
        wizard_qt_lib.messageBoxWithLog(
            self, 
            _("Fatal error"), 
            _("Fatal error occurred:\n%s\nConfiguration wizard will now quit.") % options["message"],
            options["details"]
            )
        self.close()
    def slotShowPopupDialog(self, options):
        result = qt.QMessageBox.question(
            self, #parent
            options["caption"], 
            options["message"],
            options.get("button0Text", None),
            options.get("button1Text", None),
            options.get("button2Text", qt.QString()),
            options.get("defaultButtonNumber", 0)
            )
        pageOutput = {"result" : result}
        self.emit(PYSIGNAL("signalGetPageOutput"), (pageOutput,))
    def slotProgressInfo(self, info):
        if info.has_key("text"):
            self.progressState.setText(info["text"])
        if info.has_key("details"):
            self.progressLogText += info["details"]
            self.progressLog.append(info["details"])
        if info.has_key("nextEnabled"):
            self.setNextEnabled(self.currentPage(), info["nextEnabled"])
        if info.has_key("status"):
            status = info["status"]
            if status == False:
                self.errorsFrame.show()
                self.setNextEnabled(self.currentPage(), True)


def main(args):
    if len(args) <= 1:
        print _("Not enough arguments\n")
        print _("Usage: %s repo-file\n") % args[0]
        sys.exit(1)
    app=QApplication(args)
    frontend = wizard_qt_lib.WizardUiFrontend()
    
    import one_click_install_backend
    backend = one_click_install_backend.OneClickInstallBackend(frontend, args[1])
    win=MainQtWindow(frontend, backend)
    win.setIcon(qt.QPixmap("/usr/share/icons/hicolor/64x64/apps/adept.png"))

    win.show()
    app.connect(app, SIGNAL("lastWindowClosed()"),
                app, SLOT("quit()"))
    app.exec_loop()

if __name__=="__main__":
    gettext.install('one_click_installer', tools_lib.thisScriptDirectory() + "/translations" , unicode=1)
    main(sys.argv)